Bruno Crotman
17/08/2019
Meta final: que vários dos processos de análise de dados da empresa passem a ser feitos dentro do fluxo de trabalho do R.
Ao fim do curso o objetivo é que todos os fios da meada sejam puxados para que o aluno consiga continuar por si só usando a vasta documentação disponível.
Também amo o Excel, mas amo mais as seguintes vantagens:
Reprodutibilidade. Muito mais fácil refazer uma análise com código do que point and click
Menor risco operacional. A automatização é maior, a chance de erro na execução de um passo manual é nula
Menor risco de continuidade caso haja imprevistos com a equipe.
Maior flexibilidade. Virtualmente tudo é possível
Manutenção mais fácil
Controle de versão de forma profissional
Mais fácil do que parece
Ela é feita para lidar com dados
Comunidade de usuários gigante e cooperativa
Ferramentas poderosas para comunicação dos resultados, em documentos ou aplicações
Muitos pesquisadores em métodos quantitativos que estão no estado-da-arte publicam seus métodos em bibliotecas escritas em R
Prazeroso programar
É muito comum possuirmos dados gerados em planilhas ou em algum suporte de formarto estruturado.
Neste exemplo, temos planilhas deste formato formato especificado
R é uma linguagem que é interpretada por um engine gratuito.
RStudio é o melhor ambiente de programação da linguagem R. A versão mais simples, que é totalmente funcional, é gratuita.
Na visualização padrão, ele oferece um console para execução de comandos e uma janela com a visualização dos environments, ou seja, das variáveis que ele guarda na sessão atual.
No console é possível executar comandos, como o que atribui valor a uma variável
Note que a atribuição é feita com <- e não com = como na maioria das linguagens.
Dica: o atalho alt + - gera o sinal de atribuição
Os comandos que não atribuem valor a uma variável são ecoados na tela
## [1] 3
Veja o [1] no console. O R considera que tudo é um vetor. É uma linguagem muito baseada em operações vetoriais. Isso facilita muito as coisas quando se lida com dados.
O console serve só para testes, aprendizado de novos comandos, debug, experiências etc.
Para as atividades mais comuns de análise de dados, e para que elas sejam reprodutíveis, é necessária a criação de scripts.
Eles são salvos em um arquivo de extensão “.r”
Atalhos de teclado: ctrl+enter (rodar linhas selecionadas), ctrl+shift+enter (rodar script), ctrl+1 (foco no script), ctrl+2 ** (foco no console), ctrl+shift+F10 ** (reiniciar R), ctrl+shift+C (comentar/descomentar bloco) …
Refactoring
Document outline
Pane: Files/Plots/Packages/Help/Viewer
Pane: Environment/History/Connections/Git
Jobs
Controle de versão integrado com o Github
Cheat sheets
Todo o material do curso está hospedado no Github, inclusive esta apresentação, escrita em RMarkdown.
Os exemplos de código, as imagens e os dados mostrados nesta apresentação estão inclusos no repositório do curso.
O repositório fica em github/crotman/cursoR.
Para baixar este repositório no RStudio, crie um projeto em File/New Project, do tipo Github e use o endereço do repositório: https://github.com/crotman/CursoR.git.
Todo material é disponibilizado sob a licença Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License
Para o R, simplificando para o escopo deste curso, as variáveis “armazenam” os seguintes tipos:
## [1] 1 2 3 4 5 6 7 8 9 10
## [[1]]
## [1] "oi"
##
## [[2]]
## [1] 1
## # A tibble: 10 x 2
## col1 col2
## <int> <int>
## 1 1 11
## 2 2 12
## 3 3 13
## 4 4 14
## 5 5 15
## 6 6 16
## 7 7 17
## 8 8 18
## 9 9 19
## 10 10 20
## [1] 3
## [1] "sou o b"
Existe orientação a objetos no R, mas não está no escopo deste curso
Note que não há variáveis que armazenam dado escalar, como já vimos.
Dentre os vetores há:
vetores atômicos (seus elementos são do mesmo tipo primário)
listas (seus elementos, que são vetores atômicos, são de tipos primários diferentes)
Tipos de vetores
Fonte: Advanced R
Os vetores atômicos podem ser dos seguintes tipos:
Tipos primários
Fonte: Advanced R
## [1] FALSE
## [1] "integer"
## [1] "double"
## [1] 0.1
## [1] 1500
## [1] Inf
Uma das funções mais usadas do R é c(), que cria um vetor novo vetor combinando vetores.
## [1] 1 2 3
## [1] 1 2 3 4 5 6
## [1] 1.4 2.4 3.4 4.4 5.4 6.4 7.4 8.4 9.4
O operador : é usado para gerar um vetor com todos números que estão entre os operandos e são formados somando números inteiros ao primeiro operando.
## [1] 1 2 3 4 5 6 7 8 9 10
## [1] 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5
A função seq() é usada para criar um vetor de várias formas.
Numa das formas especifica-se o valor inicial, o valor final e o incremento entre elementos do vetor.
## [1] 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6
## [18] 2.7 2.8 2.9 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 4.0 4.1 4.2 4.3
## [35] 4.4 4.5 4.6 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0
## [52] 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 7.0 7.1 7.2 7.3 7.4 7.5 7.6 7.7
## [69] 7.8 7.9 8.0 8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8 8.9 9.0 9.1 9.2 9.3 9.4
## [86] 9.5 9.6 9.7 9.8 9.9
Note que chamamos a função passando os parâmetros sem especificação de quais são eles. Eles são recebidos pela função dem específica.
Mas no R também é possível passar parâmetros de forma nomeada.
Clique em F1 enquanto tem o cursor em cima da função e veja a ordem dos parâmetros. Veja que outros parâmetros que não utilizamos. Podemos usar length.out ao invés de by:
## [1] 1 2 3 4 5 6 7 8 9 10
## [1] 1.00 3.25 5.50 7.75 10.00
Outro parâmetro, along.with, deixa que criemos um vetor num intervalo determinado e o mesmo número de elementos do vetor passado por este parâmetro.
## [1] 20.00000 28.88889 37.77778 46.66667 55.55556 64.44444 73.33333
## [8] 82.22222 91.11111 100.00000
Valores faltantes ou desconecidos são representados por NA
## [1] 1 NA
O valor NA quase sempre contamina os cálculos
## [1] NA
mas…
## [1] 1
A exceção são expressões que dão sempre o mesmo resultado independentemente do valor da variável
## [1] 1
## [1] TRUE
## [1] FALSE
A melhor forma de testar se existe um valor NA é is.na
## [1] FALSE TRUE FALSE
As operações do R são vetoriais. Numa operação entre um vetor e um escalar, a operação com o escalar é aplicada a cada elemento do vetor
## [1] 2 4 6 8 10
## [1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
Numa operação com vetores do mesmo tamanho, os elementos são pareados
## [1] 1 4 9 16 25 36 49 64 81 100
Outro conceito importante é o de recycling.
Numa operação entre dois vetores de tamanhos diferentes, o vetor menor é repetido ciclicamente de forma a ficar com o mesmo tamanho do vetor maior.
Lembra que toda variável no R é um vetor?
Então… o escalar mostrado no primeiro código do slide anterior é um vetor de 1 elemento que sofre recycling
## [1] 1 4 3 8 5 12 7 16 9 20
Existem estruturas mais complexas na linguagem construídas a partir de vetores e listas.
Data Frame
Matrix
Array
Factor
Estruturas que representam datas
Objetos (no paradigma de orientação a objetos)
Vamos passar pelo Data Frame agora. Depois por Factor e objetos que representam Datas
Data Frames, e seu primo Tibble, são estruturas muito usadas em análises de dados feitas em R.
O dataframe consiste em um conjunto de vetores nomeados, com o mesmo número de elementos, que formam uma estrutura retangular, onde cada coluna é um vetor e cada linha n contém o n-ésimo elemento dos vetores.
É similar, em muitas características, a uma tabela de banco de dados.
Essa estrutura é chave no paradigma “Tidy” que usaremos com as bibliotecas Tidyverse
Tibble é uma adaptação do Data Frame para análise de dados. Discutir essas diferenças está fora do escopo do curso. Algumas diferenças serão citadas o longo do material e justificam o uso do Tibble.
df <-
data.frame(
nome = c("João", "Maria", "Zezinho", "Juquinha"),
idade = c(7, 8, 9, 10),
altura = c(10, 11)
)
df## nome idade altura
## 1 João 7 10
## 2 Maria 8 11
## 3 Zezinho 9 10
## 4 Juquinha 10 11
#tibble não aceita recycling em vetores de tamanho diferente de 1
tib <-
#try evita que o erro paralise toda a execução do script
try(
tibble(
nome = c("João", "Maria", "Zezinho", "Juquinha"),
idade = c(7, 8, 9, 10),
altura = c(10, 11)
)
)## Error : Tibble columns must have consistent lengths, only values of length one are recycled:
## * Length 2: Column `altura`
## * Length 4: Columns `nome`, `idade`
## Backtrace:
## x
## 1. +-rmarkdown::render("D:/DataQuant/CursoR/Conteudo.Rmd", encoding = "UTF-8")
## 2. | \-knitr::knit(...)
## 3. | \-knitr:::process_file(text, output)
## 4. | +-base::withCallingHandlers(...)
## 5. | +-knitr:::process_group(group)
## 6. | \-knitr:::process_group.block(group)
## 7. | \-knitr:::call_block(x)
## 8. | \-knitr:::block_exec(params)
## 9. | +-knitr:::in_dir(...)
## 10. | \-knitr:::evaluate(...)
## 11. | \-evaluate::evaluate(...)
## 12. | \-evaluate:::evaluate_call(...)
## 13. | +-evaluate:::timing_fn(...)
## 14. | +-base:::handle(...)
## 15. | +-base::withCallingHandlers(...)
## 16. | +-base::withVisible(eval(expr, envir, enclos))
## 17. | \-base::eval(expr, envir, enclos)
## 18. | \-base::eval(expr, envir, enclos)
## 19. +-base::try(...)
## 20. | \-base::tryCatch(...)
## 21. | \-base:::tryCatchList(expr, classes, parentenv, handlers)
## 22. | \-base:::tryCatchOne(expr, names, parentenv, handlers[[1L]])
## 23. | \-base:::doTryCatch(return(expr), name, parentenv, handler)
## 24. \-tibble::tibble(...)
## 25. \-tibble:::lst_to_tibble(xlq$output, .rows, .name_repair, lengths = xlq$lengths)
## 26. \-tibble:::recycle_columns(x, .rows, lengths)
A linguagem oferece comandos de controle de fluxo similares aos de outras linguagens.
Podemos dividir os comandos de controle de fluxo em dois tipos:
choices: execução alternativa de comandos
loops: execução repetida de comandos
if, ifelseO comando if funciona para um valor lógico escalar
## [1] "2 mais 2 são 4"
Note o operador de comparação == e não =
A função if_else (da biblioteca dplyr) funciona de vetorial. if_else é mais rápida que a função ifelse da biblioteca base, mas só aceita argumentos de mesmo tipo no segundo e terceiro parâmetros
jogo_do_pim_silvio_santos <- if_else(
condition = 1:40 %% 4 == 0 ,
true = "PIM",
false = as.character(1:40)
)
jogo_do_pim_silvio_santos## [1] "1" "2" "3" "PIM" "5" "6" "7" "PIM" "9" "10" "11"
## [12] "PIM" "13" "14" "15" "PIM" "17" "18" "19" "PIM" "21" "22"
## [23] "23" "PIM" "25" "26" "27" "PIM" "29" "30" "31" "PIM" "33"
## [34] "34" "35" "PIM" "37" "38" "39" "PIM"
Note o operador %% e a função de coerção de tipo as.character
switch e case_whenA cláusula switch e a função dplyr::case_when evitam que o programador tenha que criar muitos if else aninhados
## [1] "começa com b"
Note que a condição vai sendo testada na ordem e stop gera um erro
case_when serve ao caso vetorial
## [1] "1" "par" "3" "par" "5" "par" "7"
## [8] "par" "9" "dezena" "11" "par" "13" "par"
## [15] "15" "par" "17" "par" "19" "dezena" "21"
## [22] "par" "23" "par" "25" "par" "27" "par"
## [29] "29" "dezena" "31" "par" "33" "par" "35"
## [36] "par" "37" "par" "39" "dezena"
A cláusula de loop mais usada e mais versátil é for
## [1] 1
## [1] 4
## [1] 9
## [1] 16
## [1] 25
As cláusulas next e break modificam o comportamento, respectivamente caminhando direto para a próxima iteração e saindo do for
## [1] 1
## [1] 3
## [1] 5
## [1] 1
Vamos ver que quase sempre é desnecessário usar loop para as tarefas que vamos executar.
O caráter vetorial da linguagem, aliado a funcionalidades das bibliotecas, faz com que a grande maioria dos loops sejam desnecessários.
O código fica mais limpo e expressivo e mais rápido. Às vezes MUITO mais rápido. Isso ocorre por motivos além do escopo do curso (alocação de memória, código interpretado x código compilado em C++ etc.)
O código abaixo usa loop e programação funcional, respectivamente. Programação funcional será abordada posteriormente no material.
com_loop <- function(n){
x <- integer()
for (i in 1:n){
x <- c(x, i^2)
}
x
}
#programação funcional: aprenderemos posteriomente
sem_loop <- function(n){
x <- 1:n %>%
map_dbl(function(x){x^2})
x
}Abaixo as três formas de fazer a mesma conta que terão a performance avaliada
## [1] 1 4 9 16 25
## [1] 1 4 9 16 25
## [1] 1 4 9 16 25
A biblioteca bench oferece funções ótimas para avaliar a performance de pedaços pequenos de código.
resultados_perf <- mark(
sem_loop(1e4),
com_loop(1e4),
(1:1e4)^2
)
#aprenderemos o que é %>% e select() posteriormente
resultados_perf %>%
select(expression, min, median, `itr/sec` )## # A tibble: 3 x 4
## expression min median `itr/sec`
## <bch:expr> <bch:tm> <bch:tm> <dbl>
## 1 sem_loop(10000) 6.22ms 6.69ms 143.
## 2 com_loop(10000) 88.06ms 93.71ms 9.61
## 3 (1:10000)^2 15.8us 17us 44851.
Monty Hall era uma espécie de Sílvio Santos juvenil (sub 80) americano.
Um dos seus jogos consistia em mostrar três portas ao otár… (ops) convidado. Em uma delas tem um carro.
Antes do resultado, o apresentador revela uma das portas e pergunta se o convidado que trocar a escolha.
O que vocês acham? Melhor trocar, manter a escolha original ou tanto faz?
Note o que há de interessante no código (comentado)
set.seed(88)
joga_monty_hall <- function(troca){
portas <- 1:3
#sample() sorteia elementos com ou sem reposição
porta_carro <- sample(portas, size = 1, replace = FALSE)
primeira_escolha <- 1
#Seleção negativa (retirando elementos)
portas_pra_revelar <- portas[-c(porta_carro, primeira_escolha)]
porta_revelada <- sample( c(portas_pra_revelar, portas_pra_revelar ), 1)
if(troca){
escolha <- portas[-c(primeira_escolha, porta_revelada)]
}
else{
escolha <- primeira_escolha
}
escolha == porta_carro
}
n <- 1000
#replicate executa múltiplas vezes um comando e armazena os resultados em uma estruturaúnica
troca <- replicate(n = n, joga_monty_hall(troca = TRUE))
fica <- replicate(n = n, joga_monty_hall(troca = FALSE))Resultados:
## [1] 0.675
## [1] 0.323
Vamos ver… mas dá pra simular sem saber quase nada.
Vamos usar uma das funções da família r<familia de distribuição de prob>(). Neste caso, a rbinom, que simula a distribução binomial (aquela que equivale ao evento de jogar n moedas (ou alguma coisa com dois lados) para cima e ver quantas deram cara).
n_simul <- 10000
n_questoes <- 240
min_aprovacao <- 0.6
n_aprovado <- 240 * min_aprovacao
prob_questao <- 0.2
acertos <- rbinom(n = n_simul, size = n_questoes, prob = prob_questao )
sum(acertos >= n_aprovado)/n_simul ## [1] 0
A chance é praticamente nula.
Na verdade, a grande massa da distribuição fica muito distante.
dado <- enframe(acertos/n_questoes)
mostra_chances <- function(acertos, n_questoes){
ggplot(enframe(acertos/n_questoes)) +
geom_density( aes(x = value)) +
scale_x_continuous(
labels = percent_format(accuracy = 1),
limits = c(0,1),
breaks = seq(0, 1, 0.1)
) +
labs(x ="% Acertos") +
geom_vline(xintercept = min_aprovacao, color = "red") +
theme_light()
}
mostra_chances(acertos, n_questoes)O exemplo anterior era muito simplista: ninguém chuta tudo.
Imagine que sabemos qual a chance de aparecer uma pergunta onde podemos descartar 0 alternativas, a chance de uma onde descartamos 1 e assim por diante.
#definindo a chance podermos eliminar 0, 1, 2, ... 4 alternativas
fracao_eliminar_questoes <- c( 0.1, 0.1, 0.2, 0.25 , 0.35 )
#definindo o número de questões
n_questoes_cada_elimina <- t(rmultinom(n_simul, size = n_questoes, fracao_eliminar_questoes))
probs_quando_elimina <- 1/(5:1)
acertos_concatenados <-
rbinom(
n = n_simul * 5 ,
size = as.vector(t(n_questoes_cada_elimina)),
prob = probs_quando_elimina
)## [,1] [,2] [,3] [,4] [,5]
## [1,] 23 24 50 47 96
## [2,] 24 17 48 64 87
## [3,] 23 30 43 56 88
## [4,] 20 25 51 52 92
## [1] 4 6 17 25 96 4 3 13 34 87 6 5 13 36 88 4 9 17 25 92
## [,1] [,2] [,3] [,4] [,5]
## [1,] 4 6 17 25 96
## [2,] 4 3 13 34 87
## [3,] 6 5 13 36 88
## [4,] 4 9 17 25 92
## [5,] 6 5 11 30 92
## [1] 0.3131
Arrumar os dados de forma que as linhas sejam eventos e as colunas sejam atributos do evento ajuda muito a rodar modelos e construir visualizações eficientemente.
O que é o evento e o que é o atributo pode variar até para diferentes usos do mesmo dado. Mas a prática ajuda a determinar isso.
%>%)Normalmente os tratamentos de dados são feitos em múltiplos passos encadeados:
## # A tibble: 6 x 6
## country continent year lifeExp pop gdpPercap
## <fct> <fct> <int> <dbl> <int> <dbl>
## 1 Afghanistan Asia 1952 28.8 8425333 779.
## 2 Afghanistan Asia 1957 30.3 9240934 821.
## 3 Afghanistan Asia 1962 32.0 10267083 853.
## 4 Afghanistan Asia 1967 34.0 11537966 836.
## 5 Afghanistan Asia 1972 36.1 13079460 740.
## 6 Afghanistan Asia 1977 38.4 14880372 786.
Vamos imaginar que queremos a média de PIB per capita por continente em 2007.
Note quanto código desnecessário há nestas linhas: variáveis que não precisavam ser nomeadas nem passadas explicitamente como parâmetro.
Este código desnecessário causa fadiga no programador e confunde o próprio programador e o leitor posterior do código.
#vamos cobrir essas funções de tratamento posteriormente
gapminder_07 <- filter(gapminder, year == 2007)
gapminder_07_group_continente <- group_by(gapminder_07, continent)
gapminder_media_gdp_continente <- summarise(
gapminder_07_group_continente, media_gdp = sum(gdpPercap * pop)/sum(pop)
)
resultado <- arrange(gapminder_media_gdp_continente, desc(media_gdp))
resultado## # A tibble: 5 x 2
## continent media_gdp
## <fct> <dbl>
## 1 Oceania 32885.
## 2 Europe 25244.
## 3 Americas 21603.
## 4 Asia 5432.
## 5 Africa 2561.
%>%) (cont.)O operador pipe %>% faz o seguinte:
x %>% y(z) = y(x,z)
Ou seja, o primeiro operando é enfiado como primeiro parâmetro da função que está no segundo operando.
Isso faz com que possamos escrever o código anterior assim:
resultado <- gapminder %>%
filter(year == 2007) %>%
group_by(continent) %>%
summarise(
media_gdp = sum(gdpPercap * pop) / sum(pop)
) %>%
arrange(desc(media_gdp))
resultado## # A tibble: 5 x 2
## continent media_gdp
## <fct> <dbl>
## 1 Oceania 32885.
## 2 Europe 25244.
## 3 Americas 21603.
## 4 Asia 5432.
## 5 Africa 2561.
Note que agora podemos interpretar o código facilmente como uma série de comandos de tratamento em cima dos dados.
Não é por coincidência que as funções de tratamento das bibliotecas tidyverse que veremos adiante são verbos e recebem os dados como primeiro parâmetro.
Agora o mais importante de tudo: O ATALHO PARA O %>% É CTRL + SHIFT + M
CRAN é o repositório de bibliotecas mantido pelo R com contribuição de populares.
Além de funcionalidades estatísticas e funcionalidades para lidar com dados, há dados e funcionalidades para buscar dados online.
Usaremos várias das bases como exemplo.
A primeira é a do Banco Mundial, muito rica para quem gosta de dados socioeconômicos
Para acessar um indicador precisamos achá-lo na base de indicadores com a função wbsearch()
#pattern é uma expressão regular. \\ serve para dizer que "(" é mesmo "("
#e não o ( usado nas operações de expressão regular (fora do escopo do curso)
indicadores <- wbsearch(pattern = "GINI index \\(World Bank estimate\\)")
indicadores## indicatorID indicator
## 1348 SI.POV.GINI GINI index (World Bank estimate)
Sabendo o ID do indicador, podemos consultá-lo com a função wb()
#mrv é most recent values. Pode ser usado para buscar os n valores mais recentes
gini = wb(indicator = "SI.POV.GINI", mrv= 10, POSIXct = TRUE)
head(gini)## iso3c date value indicatorID indicator iso2c
## 486 ALB 2012 29.0 SI.POV.GINI GINI index (World Bank estimate) AL
## 490 ALB 2008 30.0 SI.POV.GINI GINI index (World Bank estimate) AL
## 497 DZA 2011 27.6 SI.POV.GINI GINI index (World Bank estimate) DZ
## 530 AGO 2008 42.7 SI.POV.GINI GINI index (World Bank estimate) AO
## 541 ARG 2017 40.6 SI.POV.GINI GINI index (World Bank estimate) AR
## 542 ARG 2016 42.4 SI.POV.GINI GINI index (World Bank estimate) AR
## country date_ct granularity
## 486 Albania 2012-01-01 annual
## 490 Albania 2008-01-01 annual
## 497 Algeria 2011-01-01 annual
## 530 Angola 2008-01-01 annual
## 541 Argentina 2017-01-01 annual
## 542 Argentina 2016-01-01 annual
dplyr é uma das bibliotecas que fqzem parte do conjunto tidyverse
A função select() é usada para selecionar colunas do dataframe/tibble
## Observations: 684
## Variables: 9
## $ iso3c <chr> "ALB", "ALB", "DZA", "AGO", "ARG", "ARG", "ARG", "...
## $ date <chr> "2012", "2008", "2011", "2008", "2017", "2016", "2...
## $ value <dbl> 29.0, 30.0, 27.6, 42.7, 40.6, 42.4, 41.4, 41.0, 41...
## $ indicatorID <chr> "SI.POV.GINI", "SI.POV.GINI", "SI.POV.GINI", "SI.P...
## $ indicator <chr> "GINI index (World Bank estimate)", "GINI index (W...
## $ iso2c <chr> "AL", "AL", "DZ", "AO", "AR", "AR", "AR", "AR", "A...
## $ country <chr> "Albania", "Albania", "Algeria", "Angola", "Argent...
## $ date_ct <date> 2012-01-01, 2008-01-01, 2011-01-01, 2008-01-01, 2...
## $ granularity <chr> "annual", "annual", "annual", "annual", "annual", ...
## country date value iso3c
## 486 Albania 2012 29.0 ALB
## 490 Albania 2008 30.0 ALB
## 497 Algeria 2011 27.6 DZA
## 530 Angola 2008 42.7 AGO
## 541 Argentina 2017 40.6 ARG
## 542 Argentina 2016 42.4 ARG
É possível usar a seleção negativa assim como fizemos com vetores
## country date value
## 486 Albania 2012 29.0
## 490 Albania 2008 30.0
## 497 Algeria 2011 27.6
## 530 Angola 2008 42.7
## 541 Argentina 2017 40.6
## 542 Argentina 2016 42.4
Algumas funções helpers nos ajudam a usar a função select e são muito úteis para tratamentos mais elaborados.
Pra mostrar mais funcionalidades da função select, vamos usar uma base com dados eleitorais brasileiros, que retorna mais colunas
## Processing the data...
## Done.
## Observations: 29,113
## Variables: 58
## $ DATA_GERACAO <chr> "15/11/2018", "15/11/2018", "15...
## $ HORA_GERACAO <time> 20:03:47, 20:03:47, 20:03:47, ...
## $ ANO_ELEICAO <dbl> 2018, 2018, 2018, 2018, 2018, 2...
## $ COD_TIPO_ELEICAO <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2...
## $ NOME_TIPO_ELEICAO <chr> "ELEIÇÃO ORDINÁRIA", "ELEIÇÃO O...
## $ NUM_TURNO <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1...
## $ COD_ELEICAO <dbl> 297, 297, 297, 297, 297, 297, 2...
## $ DESCRICAO_ELEICAO <chr> "Eleições Gerais Estaduais 2018...
## $ DATA_ELEICAO <chr> "07/10/2018", "07/10/2018", "07...
## $ ABRANGENCIA <chr> "ESTADUAL", "ESTADUAL", "ESTADU...
## $ SIGLA_UF <chr> "AC", "AC", "AC", "AC", "AC", "...
## $ SIGLA_UE <chr> "AC", "AC", "AC", "AC", "AC", "...
## $ DESCRICAO_UE <chr> "ACRE", "ACRE", "ACRE", "ACRE",...
## $ CODIGO_CARGO <dbl> 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7...
## $ DESCRICAO_CARGO <chr> "DEPUTADO ESTADUAL", "DEPUTADO ...
## $ SEQUENCIAL_CANDIDATO <dbl> 10000601020, 10000603904, 10000...
## $ NUMERO_CANDIDATO <dbl> 14088, 31100, 45456, 35193, 173...
## $ NOME_CANDIDATO <chr> "ANA ISLA ARRUDA FREITAS", "MAR...
## $ NOME_URNA_CANDIDATO <chr> "ANA FREITAS", "LORA DO COMERCI...
## $ NOME_SOCIAL_CANDIDATO <chr> "#NULO#", "#NULO#", "#NULO#", "...
## $ CPF_CANDIDATO <chr> "93353405291", "63049112204", "...
## $ EMAIL_CANDIDATO <chr> "ANAFREITAS.AIF@GMAIL.COM", "JU...
## $ COD_SITUACAO_CANDIDATURA <dbl> 12, 12, 12, 12, 12, 12, 12, 12,...
## $ DES_SITUACAO_CANDIDATURA <chr> "APTO", "APTO", "APTO", "APTO",...
## $ COD_DETALHE_SITUACAO_CAND <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2...
## $ DES_DETALHE_SITUACAO_CAND <chr> "DEFERIDO", "DEFERIDO", "DEFERI...
## $ TIPO_AGREMIACAO <chr> "PARTIDO ISOLADO", "COLIGAÇÃO",...
## $ NUMERO_PARTIDO <dbl> 14, 31, 45, 35, 17, 27, 13, 13,...
## $ SIGLA_PARTIDO <chr> "PTB", "PHS", "PSDB", "PMB", "P...
## $ NOME_PARTIDO <chr> "PARTIDO TRABALHISTA BRASILEIRO...
## $ CODIGO_LEGENDA <dbl> 10000050036, 10000050109, 10000...
## $ NOME_COLIGACAO <chr> "PARTIDO ISOLADO", "FORÇA DA UN...
## $ COMPOSICAO_LEGENDA <chr> "PTB", "PMB / PHS", "PSDB / DEM...
## $ CODIGO_NACIONALIDADE <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1...
## $ DESCRICAO_NACIONALIDADE <chr> "BRASILEIRA NATA", "BRASILEIRA ...
## $ SIGLA_UF_NASCIMENTO <chr> "AC", "AC", "AC", "AC", "AC", "...
## $ CODIGO_MUNICIPIO_NASCIMENTO <dbl> -3, -3, -3, -3, -3, -3, -3, -3,...
## $ NOME_MUNICIPIO_NASCIMENTO <chr> "RIO BRANCO", "TARAUCÁ", "FEIJÓ...
## $ DATA_NASCIMENTO <chr> "12/08/1987", "10/02/1976", "12...
## $ IDADE_DATA_POSSE <dbl> 31, 42, 44, 47, 31, 26, 38, 39,...
## $ NUM_TITULO_ELEITORAL_CANDIDATO <chr> "005491592429", "001633372461",...
## $ CODIGO_SEXO <dbl> 4, 4, 4, 2, 2, 2, 2, 2, 2, 4, 2...
## $ DESCRICAO_SEXO <chr> "FEMININO", "FEMININO", "FEMINI...
## $ COD_GRAU_INSTRUCAO <dbl> 4, 3, 6, 8, 7, 6, 8, 8, 7, 8, 8...
## $ DESCRICAO_GRAU_INSTRUCAO <chr> "ENSINO FUNDAMENTAL COMPLETO", ...
## $ CODIGO_ESTADO_CIVIL <dbl> 1, 1, 3, 3, 3, 1, 3, 3, 1, 3, 3...
## $ DESCRICAO_ESTADO_CIVIL <chr> "SOLTEIRO(A)", "SOLTEIRO(A)", "...
## $ CODIGO_COR_RACA <chr> "03", "01", "01", "03", "03", "...
## $ DESCRICAO_COR_RACA <chr> "PARDA", "BRANCA", "BRANCA", "P...
## $ CODIGO_OCUPACAO <dbl> 581, 169, 999, 297, 999, 999, 2...
## $ DESCRICAO_OCUPACAO <chr> "DONA DE CASA", "COMERCIANTE", ...
## $ DESPESA_MAX_CAMPANHA <dbl> 0, -1, 0, -1, 0, 0, 0, 0, -1, 0...
## $ COD_SIT_TOT_TURNO <dbl> 5, 5, 5, 5, 5, 4, 3, 5, 5, 4, 2...
## $ DESC_SIT_TOT_TURNO <chr> "SUPLENTE", "SUPLENTE", "SUPLEN...
## $ SITUACAO_REELEICAO <chr> "N", "N", "N", "N", "N", "N", "...
## $ SITUACAO_DECLARAR_BENS <chr> "N", "N", "S", "S", "N", "N", "...
## $ NUMERO_PROTOCOLO_CANDIDATURA <dbl> -1, -1, -1, -1, -1, -1, -1, -1,...
## $ NUMERO_PROCESSO <chr> "06002996220186010000", "060045...
candidatos_select <- candidatos %>%
select(ends_with("candidato"))
datatable(head(candidatos_select))A função helper num_range ajuda a encontrar colunas do tipo prefixo_n. Isso é muito comum em bases de dados
A biblioteca worldmet retorna dados de estações meteorológicas espalhadas pelo planeta
Primeiro é necessário encontrar o código da base desejada
A função abaixo retorna os dados de uma estação. Veja que alguns campos têm um sufixo _n
dados_heathrow <- importNOAA(code = "037720-99999", year = 2019,
precip = TRUE, PWC = FALSE, parallel = TRUE)
glimpse(dados_heathrow)## Observations: 5,878
## Variables: 26
## $ date <dttm> 2019-01-01 00:00:00, 2019-01-01 01:00:00, 2019-01...
## $ usaf <chr> "037720", "037720", "037720", "037720", "037720", ...
## $ wban <chr> "99999", "99999", "99999", "99999", "99999", "9999...
## $ code <chr> "037720-99999", "037720-99999", "037720-99999", "0...
## $ station <chr> "HEATHROW", "HEATHROW", "HEATHROW", "HEATHROW", "H...
## $ lat <dbl> 51.47967, 51.47967, 51.47967, 51.47967, 51.47967, ...
## $ lon <dbl> -0.4573333, -0.4573333, -0.4573333, -0.4573333, -0...
## $ elev <dbl> 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25...
## $ wd <dbl> 283.706052, 286.994553, 290.000000, 290.000000, 27...
## $ ws <dbl> 3.266667, 3.433333, 4.100000, 3.433333, 3.266667, ...
## $ ceil_hgt <dbl> 657.3333, 667.3333, 728.0000, 768.0000, 778.3333, ...
## $ visibility <dbl> 22000, 28000, 45000, 45000, 35000, 35000, 28000, 2...
## $ air_temp <dbl> 8.666667, 8.933333, 9.000000, 9.000000, 7.966667, ...
## $ dew_point <dbl> 4.9333333, 4.9666667, 4.7666667, 4.8000000, 4.8000...
## $ atmos_pres <dbl> 1034.8, 1034.5, 1034.6, 1034.5, 1034.4, 1033.9, 10...
## $ RH <dbl> 77.67802, 76.42835, 75.06237, 75.23079, 80.81974, ...
## $ cl_1 <dbl> 7.666667, 8.000000, 7.666667, 8.000000, 7.666667, ...
## $ cl_1_height <dbl> 657.3333, 667.3333, 728.0000, 768.0000, 778.3333, ...
## $ cl_2 <dbl> 8.000000, NA, 8.000000, NA, NA, NA, 7.000000, 7.00...
## $ cl_2_height <dbl> 792, NA, 914, NA, NA, NA, 1006, 1036, NA, 720, 121...
## $ cl_3 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
## $ cl_3_height <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
## $ precip_12 <dbl> NA, NA, NA, NA, NA, NA, 0, NA, NA, NA, NA, NA, NA,...
## $ precip_6 <dbl> 0, NA, NA, NA, NA, NA, 0, NA, NA, NA, NA, NA, 0, N...
## $ cl <dbl> 8.000000, 8.000000, 8.000000, 8.000000, 7.666667, ...
## $ precip <dbl> NA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...
dados_heathrow_select <- dados_heathrow %>%
select(
date,
num_range("cl_", 1:3 ),
num_range("precip_", c(6, 12))
)
head(dados_heathrow_select)## # A tibble: 6 x 6
## date cl_1 cl_2 cl_3 precip_6 precip_12
## <dttm> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2019-01-01 00:00:00 7.67 8 NA 0 NA
## 2 2019-01-01 01:00:00 8 NA NA NA NA
## 3 2019-01-01 02:00:00 7.67 8 NA NA NA
## 4 2019-01-01 03:00:00 8 NA NA NA NA
## 5 2019-01-01 04:00:00 7.67 NA NA NA NA
## 6 2019-01-01 05:00:00 6 NA NA NA NA
dados_heathrow_select <- dados_heathrow %>%
select(
date,
air_temp,
everything()
)
glimpse(dados_heathrow_select)## Observations: 5,878
## Variables: 26
## $ date <dttm> 2019-01-01 00:00:00, 2019-01-01 01:00:00, 2019-01...
## $ air_temp <dbl> 8.666667, 8.933333, 9.000000, 9.000000, 7.966667, ...
## $ usaf <chr> "037720", "037720", "037720", "037720", "037720", ...
## $ wban <chr> "99999", "99999", "99999", "99999", "99999", "9999...
## $ code <chr> "037720-99999", "037720-99999", "037720-99999", "0...
## $ station <chr> "HEATHROW", "HEATHROW", "HEATHROW", "HEATHROW", "H...
## $ lat <dbl> 51.47967, 51.47967, 51.47967, 51.47967, 51.47967, ...
## $ lon <dbl> -0.4573333, -0.4573333, -0.4573333, -0.4573333, -0...
## $ elev <dbl> 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25...
## $ wd <dbl> 283.706052, 286.994553, 290.000000, 290.000000, 27...
## $ ws <dbl> 3.266667, 3.433333, 4.100000, 3.433333, 3.266667, ...
## $ ceil_hgt <dbl> 657.3333, 667.3333, 728.0000, 768.0000, 778.3333, ...
## $ visibility <dbl> 22000, 28000, 45000, 45000, 35000, 35000, 28000, 2...
## $ dew_point <dbl> 4.9333333, 4.9666667, 4.7666667, 4.8000000, 4.8000...
## $ atmos_pres <dbl> 1034.8, 1034.5, 1034.6, 1034.5, 1034.4, 1033.9, 10...
## $ RH <dbl> 77.67802, 76.42835, 75.06237, 75.23079, 80.81974, ...
## $ cl_1 <dbl> 7.666667, 8.000000, 7.666667, 8.000000, 7.666667, ...
## $ cl_1_height <dbl> 657.3333, 667.3333, 728.0000, 768.0000, 778.3333, ...
## $ cl_2 <dbl> 8.000000, NA, 8.000000, NA, NA, NA, 7.000000, 7.00...
## $ cl_2_height <dbl> 792, NA, 914, NA, NA, NA, 1006, 1036, NA, 720, 121...
## $ cl_3 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
## $ cl_3_height <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
## $ precip_12 <dbl> NA, NA, NA, NA, NA, NA, 0, NA, NA, NA, NA, NA, NA,...
## $ precip_6 <dbl> 0, NA, NA, NA, NA, NA, 0, NA, NA, NA, NA, NA, 0, N...
## $ cl <dbl> 8.000000, 8.000000, 8.000000, 8.000000, 7.666667, ...
## $ precip <dbl> NA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...
mutate
-read_csv
-read_fwf
-read_excel
manobras com vars, starts_with, num_range etc
n_simul <- 10000
n_questoes <- 240
min_aprovacao <- 0.6
n_aprovado <- 240 * min_aprovacao
prob_questao <- 0.2
estimar_chance <- function(...){
print("aqui")
fracao_eliminar_questoes <- as.vector(...)
#definindo o número de questões
n_questoes_cada_elimina <- t(rmultinom(n_simul, size = n_questoes, fracao_eliminar_questoes))
probs_quando_elimina <- 1/(5:1)
acertos_concatenados <-
rbinom(
n = n_simul * 5 ,
size = as.vector(t(n_questoes_cada_elimina)),
prob = probs_quando_elimina
)
matriz_acertos <- matrix(acertos_concatenados, byrow = TRUE, nrow = n_simul )
acertos <- rowSums(matriz_acertos)
sum(acertos > n_aprovado)/n_simul
}
#definindo a chance podermos eliminar 0, 1, 2, ... 4 alternativas
resultados <- RandVec(n = 5, m = 100) %>%
.$RandVecOutput %>%
t() %>%
as_tibble() %>%
mutate(id = row_number()) %>%
group_by(id) %>%
nest() %>%
mutate(data_fica = data) %>%
mutate(data = map(data, estimar_chance) ) %>%
unnest()## Warning: `as_tibble.matrix()` requires a matrix with column names or a `.name_repair` argument. Using compatibility `.name_repair`.
## This warning is displayed once per session.
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"